<template>
  <router
    :show-unread-view="showUnreadView"
    :show-campaign-view="showCampaignView"
    :is-mobile="isMobile"
    :has-fetched="hasFetched"
    :unread-message-count="unreadMessageCount"
    :is-left-aligned="isLeftAligned"
    :hide-message-bubble="hideMessageBubble"
    :show-popout-button="showPopoutButton"
  />
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
import { setHeader } from 'widget/helpers/axios';
import { IFrameHelper, RNHelper } from 'widget/helpers/utils';
import Router from './views/Router';
import { getLocale } from './helpers/urlParamsHelper';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import { isEmptyObject } from 'widget/helpers/utils';
import ActionCableConnector from './helpers/actionCable';

export default {
  name: 'App',
  components: {
    Router,
  },
  data() {
    return {
      showUnreadView: false,
      showCampaignView: false,
      isMobile: false,
      hideMessageBubble: false,
      widgetPosition: 'right',
      showPopoutButton: false,
      isWebWidgetTriggered: false,
    };
  },
  computed: {
    ...mapGetters({
      activeCampaign: 'campaign/getActiveCampaign',
      authToken: 'appConfig/getAuthToken',
      campaigns: 'campaign/getCampaigns',
      contact: 'appConfig/getContact',
      hasFetched: 'agent/getHasFetched',
      isWidgetConfigured: 'appConfig/getWidgetConfigured',
      messageCount: 'conversation/getMessageCount',
      unreadMessageCount: 'conversation/getUnreadMessageCount',
      webChannelConfig: 'appConfig/getWebChannelConfig',
    }),
    isLeftAligned() {
      const isLeft = this.widgetPosition === 'left';
      return isLeft;
    },
    isIFrame() {
      return IFrameHelper.isIFrame();
    },
    isRNWebView() {
      return RNHelper.isRNWebView();
    },
  },
  watch: {
    activeCampaign() {
      this.setCampaignView();
    },
    isWidgetConfigured() {
      const { pubsubToken } = this.contact || {};
      window.chatwootPubsubToken = pubsubToken;
      window.actionCable = new ActionCableConnector(
        window.WOOT_WIDGET,
        window.chatwootPubsubToken
      );
      const { websiteToken, locale } = this.webChannelConfig;
      this.setLocale(locale);
      if (this.isIFrame) {
        this.registerListeners();
        this.sendLoadedEvent();
        setHeader('X-Auth-Token', this.authToken);
      } else {
        setHeader('X-Auth-Token', this.authToken);
        this.fetchOldConversations();
        this.fetchAvailableAgents(websiteToken);
        this.setLocale(getLocale(window.location.search));
      }
      if (this.isRNWebView) {
        this.registerListeners();
        this.sendRNWebViewLoadedEvent();
      }
      this.$store.dispatch('conversationAttributes/getAttributes');
      this.registerUnreadEvents();
      this.registerCampaignEvents();
    },
  },
  mounted() {
    const url = new URL(window.location.href);
    this.$store.dispatch('appConfig/fetchAppConfig', {
      token: url.searchParams.get('cw_conversation'),
      websiteToken: url.searchParams.get('website_token'),
    });
  },
  methods: {
    ...mapActions('conversation', ['fetchOldConversations', 'setUserLastSeen']),
    ...mapActions('campaign', ['initCampaigns', 'executeCampaign']),
    ...mapActions('agent', ['fetchAvailableAgents']),
    scrollConversationToBottom() {
      const container = this.$el.querySelector('.conversation-wrap');
      container.scrollTop = container.scrollHeight;
    },
    setBubbleLabel() {
      IFrameHelper.sendMessage({
        event: 'setBubbleLabel',
        label: this.$t('BUBBLE.LABEL'),
      });
    },
    setLocale(locale) {
      const { enabledLanguages } = this.webChannelConfig;
      if (enabledLanguages.some(lang => lang.iso_639_1_code === locale)) {
        this.$root.$i18n.locale = locale;
      }
    },
    setPosition(position) {
      const widgetPosition = position || 'right';
      this.widgetPosition = widgetPosition;
    },
    setHideMessageBubble(hideBubble) {
      this.hideMessageBubble = !!hideBubble;
    },
    registerUnreadEvents() {
      bus.$on('on-agent-message-recieved', () => {
        if (!this.isIFrame) {
          this.setUserLastSeen();
        }
        this.setUnreadView();
      });
      bus.$on('on-unread-view-clicked', () => {
        this.unsetUnreadView();
        this.setUserLastSeen();
      });
    },
    registerCampaignEvents() {
      bus.$on('on-campaign-view-clicked', campaignId => {
        const { websiteToken } = this.webChannelConfig;
        this.showCampaignView = false;
        this.showUnreadView = false;
        this.unsetUnreadView();
        this.setUserLastSeen();
        this.executeCampaign({ campaignId, websiteToken });
      });
    },
    setPopoutDisplay(showPopoutButton) {
      this.showPopoutButton = showPopoutButton;
    },
    setCampaignView() {
      const { messageCount, activeCampaign } = this;
      const isCampaignReadyToExecute =
        !isEmptyObject(activeCampaign) &&
        !messageCount &&
        !this.isWebWidgetTriggered;
      if (this.isIFrame && isCampaignReadyToExecute) {
        this.showCampaignView = true;
        IFrameHelper.sendMessage({ event: 'setCampaignMode' });
      }
    },
    setUnreadView() {
      const { unreadMessageCount } = this;
      if (this.isIFrame && unreadMessageCount > 0) {
        IFrameHelper.sendMessage({
          event: 'setUnreadMode',
          unreadMessageCount,
        });
      }
    },
    unsetUnreadView() {
      if (this.isIFrame) {
        IFrameHelper.sendMessage({ event: 'resetUnreadMode' });
      }
    },
    createWidgetEvents(message) {
      const { eventName } = message;
      const isWidgetTriggerEvent = eventName === 'webwidget.triggered';
      this.isWebWidgetTriggered = true;
      if (
        isWidgetTriggerEvent &&
        (this.showUnreadView || this.showCampaignView)
      ) {
        return;
      }
      this.setUserLastSeen();
      this.$store.dispatch('events/create', { name: eventName });
    },
    registerListeners() {
      const { websiteToken } = this.webChannelConfig;
      window.addEventListener('message', e => {
        if (!IFrameHelper.isAValidEvent(e)) {
          return;
        }
        const message = IFrameHelper.getMessage(e);
        if (message.event === 'config-set') {
          this.setLocale(message.locale);
          this.setBubbleLabel();
          this.setPosition(message.position);
          this.fetchOldConversations().then(() => this.setUnreadView());
          this.setPopoutDisplay(message.showPopoutButton);
          this.fetchAvailableAgents(websiteToken);
          this.setHideMessageBubble(message.hideMessageBubble);
          this.$store.dispatch('contacts/get');
        } else if (message.event === 'widget-visible') {
          this.scrollConversationToBottom();
        } else if (message.event === 'change-url') {
          const { referrerURL, referrerHost } = message;
          this.initCampaigns({ currentURL: referrerURL, websiteToken });
          window.referrerURL = referrerURL;
          bus.$emit(BUS_EVENTS.SET_REFERRER_HOST, referrerHost);
        } else if (message.event === 'toggle-close-button') {
          this.isMobile = message.showClose;
        } else if (message.event === 'push-event') {
          this.createWidgetEvents(message);
        } else if (message.event === 'set-label') {
          this.$store.dispatch('conversationLabels/create', message.label);
        } else if (message.event === 'remove-label') {
          this.$store.dispatch('conversationLabels/destroy', message.label);
        } else if (message.event === 'set-user') {
          this.$store.dispatch('contacts/update', message);
        } else if (message.event === 'set-custom-attributes') {
          this.$store.dispatch(
            'contacts/setCustomAttributes',
            message.customAttributes
          );
        } else if (message.event === 'delete-custom-attribute') {
          this.$store.dispatch('contacts/setCustomAttributes', {
            [message.customAttribute]: null,
          });
        } else if (message.event === 'set-locale') {
          this.setLocale(message.locale);
          this.setBubbleLabel();
        } else if (message.event === 'set-unread-view') {
          this.showUnreadView = true;
          this.showCampaignView = false;
        } else if (message.event === 'unset-unread-view') {
          this.showUnreadView = false;
          this.showCampaignView = false;
        }
      });
    },
    sendLoadedEvent() {
      IFrameHelper.sendMessage({
        event: 'loaded',
        config: {
          authToken: this.authToken,
          channelConfig: this.webChannelConfig,
        },
      });
    },
    sendRNWebViewLoadedEvent() {
      RNHelper.sendMessage({
        event: 'loaded',
        config: {
          authToken: this.authToken,
          channelConfig: this.webChannelConfig,
        },
      });
    },
  },
};
</script>

<style lang="scss">
@import '~widget/assets/scss/woot.scss';
</style>
